package com.baohua.service.impl;

import java.io.UnsupportedEncodingException;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import net.sf.json.JsonConfig;

import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Component;

import com.baohua.dao.DictionaryDao;
import com.baohua.dao.OrderDao;
import com.baohua.exception.BaohuaSystemException;
import com.baohua.model.Dictionary;
import com.baohua.model.DiningTable;
import com.baohua.model.Goods;
import com.baohua.model.OrdDinTabRel;
import com.baohua.model.OrderDetails;
import com.baohua.model.OrderHeader;
import com.baohua.service.OrderService;
import com.baohua.util.StringUtil;
import com.baohua.util.UUIDCode;

/**
 * 订单的业务逻辑
 * @author Happy Everyday
 *
 */
@Component("orderService")
public class OrderServiceImpl implements OrderService {
	
	private OrderDao orderDao;
	private DictionaryDao dictionaryDao;
	
	@Override
	public JSONArray getAllDiningTable(String hasBeanSelectedTable) {
		List<DiningTable> tables = orderDao.queryAllDiningTable();
		List<Dictionary> dtnies = dictionaryDao.findDictionaryByPIdAndCode(StringUtil.TABLE_CATEGORY_CODE);
		String[] selectedTab = hasBeanSelectedTable.split(StringUtil.DELIMITER);
		List<String> list = new ArrayList<String>();
	
		for(int i = 0; i < dtnies.size(); i++) {
			Dictionary d = dtnies.get(i);
			list.add("{id: "+ d.getDictionaryId() + ", pid: 0, text: '" + d.getCategoryName() +"'}");	//餐桌以json格式的数据封装到list<String>中
			for(int j = 0; j < tables.size(); j++) {
				DiningTable t = tables.get(j);
				if(t.getDiningTableCategory() == d.getDictionaryId()) {//判断是否属于该类型的餐桌，如果是，则添加到该节点下。
					String code = "{id: 't_"+ t.getDiningTableId() + "', pid: " + t.getDiningTableCategory() + ", text: '" + t.getDiningTableName() +"'";
					for(int k = 0; k < selectedTab.length; k++) {
						if(StringUtils.equals(selectedTab[k], t.getDiningTableName()))
							code = code + ", ischecked: true";
					}
					code = code + " }";
					list.add(code);
				}
			}
		}
		JSONArray ja = JSONArray.fromObject(list);
		return ja;
	}
	
	@Override
	public boolean modifyOrder(String modifyMsg) {
		boolean success = false;
		
		if(StringUtils.isEmpty(modifyMsg)) return success;
		String orderStr = "";
		try {
			orderStr = new String(modifyMsg.getBytes("ISO-8859-1"), "UTF-8");
		} catch (UnsupportedEncodingException e) {
			new BaohuaSystemException("出错了！");
		}
		//需要修改的订单信息（封装成了json格式）
		JSONObject jo = JSONObject.fromObject(orderStr);
		String categoryCode = jo.getString("codeValue");//订单种类代码，（不会是空值）
		if(StringUtils.isEmpty(categoryCode))
			return success;
		
		//获取订单的ID
		long orderHeaderId = jo.getLong("orderHeaderId");
		OrderHeader orderHeader = new OrderHeader();
		orderHeader.setOrderHeaderId(orderHeaderId);
		
		//需要修改的商品信息:修改订单的商品只能修改商品的数量和总价
		JSONArray modifyGoods = jo.getJSONArray("modifyGoods");
		if(!modifyGoods.isEmpty())
			modifyOrder_modifyGoods(modifyGoods);
		
		//需要添加的商品：商品信息
		JSONArray addGoods = jo.getJSONArray("addGoods");
		if(!addGoods.isEmpty())
			addOrderDetails(addGoods, orderHeader);
		
		//删除商品：只需要订单明细Id，即单个商品的唯一标示
		JSONArray delGoods = jo.getJSONArray("delGoods");
		if(!delGoods.isEmpty())
			modifyOrder_delGoods(delGoods);
		
		/**订单和餐桌的关系表的操作**/
		String tableOperationStatus = jo.getString("tableOperationStatus");
		if(StringUtils.equals(tableOperationStatus, "-1")) {	//状态为-1，删除所有的订单-餐桌关系
			orderDao.deleteOrdTabRelByOrderHeaderId(orderHeaderId);
		} else if(StringUtils.equals(tableOperationStatus, "1")) { 	//状态是1，餐桌有添加和修改。
			JSONArray delTable = jo.getJSONArray("delTable");
			JSONArray addTable = jo.getJSONArray("addTable");
			if(!delTable.isEmpty())	//为空，没有需要删除的餐桌
				orderDao.deleteTableByJA(delTable, orderHeaderId);
			if(!addTable.isEmpty()) {//为空，没有需要添加的餐桌
				List<OrdDinTabRel> odtrList = new ArrayList<OrdDinTabRel>();
				for(int i = 0; i < addTable.size(); i++) {
					OrdDinTabRel odtr = new OrdDinTabRel();
					DiningTable dt = new DiningTable();
					
					JSONObject atjo = addTable.getJSONObject(i);
					long diningTableId = atjo.getLong("diningTableId");
					
					dt.setDiningTableId(diningTableId);
					odtr.setDiningTable(dt);
					odtr.setOrderHeader(orderHeader);
					odtrList.add(odtr);
				}
				orderDao.addTables(odtrList);
			}
		}
		
		String deliveryAddress = jo.getString("deliveryAddress");
		long orderCategory = jo.getLong("orderCategory");
		String mealTimeStr = jo.getString("mealTime");
		String remark = jo.getString("remark");
		String memberNo = jo.getString("memberNo");
		String memberName = jo.getString("memberName");
		String diningTableName = jo.getString("diningTableName");
		String memberIdStr = jo.getString("memberId");
		
		StringBuilder hql = new StringBuilder("update OrderHeader o set o.orderCategory = " + orderCategory);
		hql.append(", o.deliveryAddress = '" +  deliveryAddress + "'");
		hql.append(", o.remark = '" + remark + "'");
		hql.append(", o.diningTableName = '" + diningTableName + "'");
		
    	if(!StringUtils.isEmpty(mealTimeStr)) {//用餐时间
    		//Timestamp时间格式的转换对格式的要求非常严密，所以如果修改过的时间格式是：2013-04-27 11:55。
    		//没有修改过的时间格式是：2013-04-27 11:55:00，有所区别，在这里需要精确到”秒“单位。
    		if(!(mealTimeStr.split(":").length == 3))
    			mealTimeStr = mealTimeStr + ":00";			//mealTimeStr的格式为：2013-04-27 11:55
    		Timestamp mealTime = Timestamp.valueOf(mealTimeStr);
    		hql.append(", o.mealTime = '" + mealTime + "'");
    	}
    	if(!StringUtils.isEmpty(memberIdStr)){//会员Id如果为空，会员账号和会员姓名也为空。
    		long memberId = Long.parseLong(memberIdStr);
    		hql.append(", o.memberNo = '" + memberNo + "', o.memberId = " + memberId + ", o.memberName = '" + memberName + "'");
    	}
    	//如果没有对订单明细进行修改，订单的总价和商品总数就是原来的，无需改动。
    	if(!modifyGoods.isEmpty() || !addGoods.isEmpty() || !delGoods.isEmpty()) {
    		int amount = orderDao.findGoodsCountByOrderHeaderId(orderHeaderId);
        	double totalPrice = orderDao.findGoodsTotalPriceByOrderHeaderId(orderHeaderId);
        	hql.append(", o.amount = " + amount + ", o.orderTotalPrice = " + totalPrice);
    	}
    	hql.append(" where o.orderHeaderId = " + orderHeaderId);
    	orderDao.updateOrderHeader(hql.toString());
    	success = true;
		return success;
	}
	
	/**删除订单明细信息**/
	@SuppressWarnings("unchecked")
	private void modifyOrder_delGoods(JSONArray delGoods) {
		List<OrderDetails> lists = (List<OrderDetails>)JSONArray.toList(delGoods, OrderDetails.class);
		orderDao.deleteOrderDetails(lists);
	}
	/**修改订单明细信息**/
	private void modifyOrder_modifyGoods(JSONArray modifyGoods){
		orderDao.updateOrderDetails(modifyGoods);
	}
	/**
	 * 存储订单明细
	 */
	private void addOrderDetails(JSONArray jaGoods, OrderHeader oh) {
		List<OrderDetails> ODLists = new ArrayList<OrderDetails>();
		for(int i = 0; i < jaGoods.size(); i++ ) {
			JSONObject joGoods = JSONObject.fromObject(jaGoods.get(i));
			OrderDetails ods = new OrderDetails();
			Goods goods = new Goods();
			
			double up = joGoods.getDouble("unitPrice"); //单价
			int amt = joGoods.getInt("amount"); //数量
			double gsTotalPrice = up * amt; //单个菜的总价
			
			goods.setGoodsId(joGoods.getLong("goodsId"));
			ods.setGoods(goods);
			ods.setGoodsName(joGoods.getString("goodsName"));
			ods.setGoodsUnitPrice(up);
			ods.setAmount(amt);
			ods.setAccountedTime(new Date());
			ods.setGoodsTotalSalesPrice(gsTotalPrice);
			ods.setOrderHeader(oh);
			ODLists.add(ods);
		}
		orderDao.saveListOrderDetails(ODLists);
	}
	
	@Override
	public List<Goods> findAllGoods() {
		return orderDao.findAllGoods();
	}
	
	@Override
	public boolean updateOrder(long orderHeaderId) {
		boolean success = false;
		if(orderHeaderId <= 0)
			return success;
		int count = orderDao.updateOrderByOrderHeaderId(orderHeaderId, dictionaryDao.findIdByCode(StringUtil.ORDER_INVALID_CODE));
		if(count == 1)
			success = true;
		return success;
	}

	@Override
	public List<OrderDetails> findOrderDetailsByOrderHeaderId(String orderHeaderStr){
		JSONObject jo = JSONObject.fromObject(orderHeaderStr);
		long orderHeaderId = jo.getLong("orderHeaderId");
		
		List<OrderDetails> lists = (List<OrderDetails>)orderDao.findOrderDetailsByOrderHeaderId(orderHeaderId);
		
		return lists;
	}
	
	@Override
	public List<Dictionary> findDictionarysByCode(String... categoryCodes) {
		return dictionaryDao.findDictionarysByCode(categoryCodes);
	}
	
	@Override
	public List<Dictionary> findDictionaryByParentCode(String... categoryCodes) {
		return dictionaryDao.findDictionaryByPIdAndCode(categoryCodes);
	}
	
	
	@Override
	public Map<Long, String> findDictionaryByPIdAndCode(String... categoryCodes) {
		Map<Long, String> maps = new HashMap<Long, String>();
		List<Dictionary> dtys = dictionaryDao.findDictionaryByPIdAndCode(categoryCodes);
		
		/**将获取的Category放到Map里面**/
		for(int i = 0; i < dtys.size(); i++) {
			Dictionary dty = dtys.get(i);
			maps.put(dty.getDictionaryId(), dty.getCategoryName());
		}
		return maps;
	}
	
	@Override
	public long queryCountOrderHeader(String searchCondition) throws UnsupportedEncodingException {
		String where_Sql = "";
		String cdtn = "";
		if(StringUtils.isNotEmpty(searchCondition)) {
			cdtn = new String(searchCondition.getBytes("ISO-8859-1"),"UTF-8");
			where_Sql = getSql(cdtn);//获取查询时候的where语句
		}
		return orderDao.queryCountOrderHeader(where_Sql);
	}
	
	@Override
	public JSONArray findListOrderHeader(String searchCondition, int startPost, int pageSize) throws UnsupportedEncodingException{
		
		String where_Sql = "";
		String cdtn = "";
		if(StringUtils.isNotEmpty(searchCondition)) {
			cdtn = new String(searchCondition.getBytes("ISO-8859-1"),"UTF-8");
			where_Sql = getSql(cdtn);//获取查询时候的where语句
		}
			
		/**获取订单状态和订单种类的字典**/
		Map<Long, String> map = findDictionaryByPIdAndCode(StringUtil.ORDER_STATUS_CODE, StringUtil.ORDER_CATEGORY_CODE);
		
		//订单头信息
		List<OrderHeader> lists = orderDao.findListOrderHeader(where_Sql, startPost, pageSize);
		
		JsonConfig jsonConfig = new JsonConfig();
		//防止序列化为json格式的时候出现死循环，排除掉数组里面的类型
		jsonConfig.setExcludes(new String[]{"orderdetails", "ordDinTabRel"});
//		jsonConfig.registerJsonBeanProcessor(Date.class, new JsDateJsonBeanProcessor());
		//根据jsonConfig的要求将lists格式化为JSONArray格式
		JSONArray ja = JSONArray.fromObject(lists, jsonConfig);
		
		for(int i = 0; i< ja.size(); i++) {
			
			/**************************************
			 * 这里还需要把服务员传进来，根据其Id设置成相应的名字
			 **************************************/
			
			JSONObject jo = ja.getJSONObject(i);
			/**
			 * json解析的日期类型为：{"mealTime":{"nanos":0,"time":1366128000000,"minutes":0,"seconds":0,"hours":0,"month":3,"timezoneOffset":-480,"year":113,"day":3,"date":17},
			 * js读取出来是个object类型，需要处理，这里直接转化为字符串然后在存回JSONArray里。
			 */
			String mealTim = lists.get(i).getMealTime().toString();
			jo.put("mealTime", mealTim.substring(0, mealTim.length()-2));
			jo.put("orderDate", lists.get(i).getOrderDate().toString().split(" ")[0]);
			/**
			 * 订单状态和种类存的是字典的ID，改为相应的种类和状态。
			 */
			jo.put("orderCategory", map.get(lists.get(i).getOrderCategory()));
			jo.put("orderStatus", map.get(lists.get(i).getOrderStatus()));
		}
		return ja;
	}
	
	/**
	 * 查询订单头信息的sql
	 * @param searchCondition
	 * @return
	 */
	private String getSql(String searchCondition) {
		String hql = "";
		
		JSONObject jo = JSONObject.fromObject(searchCondition);
		
		String documentNumber = jo.getString("documentNumber");
		String orderCategory = jo.getString("orderCategory");
		String orderStatus = jo.getString("orderStatus");
		String orderDate = jo.getString("orderDate");
		String deliveryAddress = jo.getString("deliveryAddress");
		String diningTableName = jo.getString("diningTableName");
		
		if(!StringUtils.isEmpty(documentNumber)) {
			hql = hql + "and o.documentNumber = '" + documentNumber + "' ";
		}
		if(!StringUtils.isEmpty(orderCategory)) {
			hql = hql + "and o.orderCategory = '" + orderCategory + "' ";
		}
		if(!StringUtils.isEmpty(orderStatus)) {
			hql = hql + "and o.orderStatus = '" + orderStatus + "' ";
		}
		
		if(!StringUtils.isEmpty(deliveryAddress)) {
			hql = hql + "and o.deliveryAddress like '%" + deliveryAddress + "%' ";
		}
		if(!StringUtils.isEmpty(orderDate)) {
			hql = hql + "and o.orderDate = '" + orderDate + "' ";
		}
		if(!StringUtils.isEmpty(diningTableName)) {
			hql = hql + "and o.diningTableName like '" + diningTableName + "%' ";
		}
		return hql;
	}
	
	@Override
	public List<Dictionary> findCategoryByCode(String menuCode) {
		return dictionaryDao.findDictionaryByCode(menuCode);
	}

	@Override
	public List<Goods> findDishByGoodsCategory(long categoryId) {
		return orderDao.findDishByGoodsCategory(categoryId);
	}

	@Override
	public List<DiningTable> findDiningTableByCategoryId(long categoryId) {
		return orderDao.findDiningTableByCategoryId(categoryId);
	}

	@Override
	public boolean addOrder(String orderString) throws BaohuaSystemException {
		
		boolean success = false;
		
		if(StringUtils.isEmpty(orderString))//json字符串为空，return false；
			return false;
		/**
		 * 先获取订单头信息
		 */
		JSONObject jo = JSONObject.fromObject(orderString);//解析传过来的Json字符串
		
		JSONArray jaGoods = jo.getJSONArray("goods");//商品明细不能为空
		if(jaGoods.isEmpty())
			return false;
		
		String ordCtgyStr = jo.getString("orderCategory"); //获取订单类型
		if(StringUtils.isEmpty(ordCtgyStr))//订单类型不能为空
			return false;
		
		long orderCategory = dictionaryDao.findIdByCode(ordCtgyStr);
		if(orderCategory == StringUtil.ERROR_NUMBER)//orderCategory == -1
			return false;
		
		/**
		 * 用餐餐桌、外卖地址
		 */
		String table = "";
		String delAddr = jo.getString("deliveryAddress");
		JSONArray jaTable = jo.getJSONArray("table");
		
		if(!StringUtils.equals(ordCtgyStr, StringUtil.TAKE_OUT_CODE)) {//只有外卖不需要餐桌
			if(jaTable.isEmpty()) //餐馆吃饭，餐桌不能为空
				return false;
			for(int i = 0; i < jaTable.size(); i++) {
				JSONObject joTable = JSONObject.fromObject(jaTable.get(i));
				table = table + joTable.getString("tableName") + StringUtil.DELIMITER;
			}
			table = table.substring(0, table.length()-1);
		} else {
			if(StringUtils.isEmpty(delAddr))//送外卖需要地址不为空
				return false;
		}
		
		/**
		 * 用餐时间
		 */
		Date date = new Date();
		Timestamp timestamp = new Timestamp(date.getTime());
		//预订用餐时间,时间必须符合：2013-04-18 15:20:00这种格式，不足十位数用0不足，比如：04。jdk1.6要求比较严格
		String mealTimeStr = jo.getString("mealTime") + ":00";
		if(!StringUtils.isEmpty(jo.getString("mealTime"))){//用餐时间不为空，餐桌点餐（时间为空），默认系统时间。
			timestamp = Timestamp.valueOf(mealTimeStr);
		}
		
		OrderHeader orderHeader = new OrderHeader();//创建orderHeader实体
		
		/**订单状态：默认是（已下单，待结账）**/
		long orderStatus = dictionaryDao.findIdByCode(StringUtil.ORDER_ON_ORDERS_IN_CODE);
		
		/**还有服务员，服务员编号,服务类别,这里先不存储..*****/
		orderHeader.setOrderTotalPrice(jo.getDouble("totalPrice"));
		orderHeader.setAmount(jo.getInt("amount"));
		orderHeader.setDeliveryAddress(jo.getString("deliveryAddress"));
		orderHeader.setOrderCategory(orderCategory);
		orderHeader.setRemark(jo.getString("remark"));
		orderHeader.setDocumentNumber(UUIDCode.getUUIDCode(StringUtil.ORDER_CODE_PREFIX));//订单编号
		orderHeader.setDiningTableName(table);
		orderHeader.setOrderDate(new Date());
		orderHeader.setOrderStatus(orderStatus);
		orderHeader.setMealTime(timestamp);
		/**会员信息**/
		String memberIdStr = jo.getString("memberId");
		if(!StringUtils.isEmpty(memberIdStr)) {
			long memberId = Long.parseLong(memberIdStr);
			orderHeader.setMemberId(memberId);
			orderHeader.setMemberNo(jo.getString("memberNo"));
			orderHeader.setMemberName(jo.getString("memberName"));
		}
		
		//订单的Id
		long orderHeaderId = orderDao.saveOrderHeader(orderHeader);
		OrderHeader oh = orderHeader;
		oh.setOrderHeaderId(orderHeaderId);
		
		/**
		 * 存储订单餐桌关系
		 */
		if(!StringUtils.equals(ordCtgyStr, StringUtil.TAKE_OUT_CODE)) {
			List<OrdDinTabRel> lists = new ArrayList<OrdDinTabRel>();
			for(int i = 0; i < jaTable.size(); i++) {
				JSONObject joTable = JSONObject.fromObject(jaTable.get(i));
				
				OrdDinTabRel ortr = new OrdDinTabRel();
				DiningTable dining = new DiningTable();
				
				dining.setDiningTableId(joTable.getLong("tableId"));
				ortr.setDiningTable(dining);
				
				ortr.setOrderHeader(oh);
				lists.add(ortr);
			}
			orderDao.saveListOrderDining(lists);
		}
		
		/**存储订单明细**/
		addOrderDetails(jaGoods, oh);
		
		success = true;
		return success;
		
	}
	
	public DictionaryDao getDictionaryDao() {
		return dictionaryDao;
	}
	@Resource(name="dictionaryDao")
	public void setDictionaryDao(DictionaryDao dictionaryDao) {
		this.dictionaryDao = dictionaryDao;
	}
	public OrderDao getOrderDao() {
		return orderDao;
	}
	@Resource(name="orderDao")
	public void setOrderDao(OrderDao orderDao) {
		this.orderDao = orderDao;
	}

}
